package com.ruoyi.gateway.filter;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.gateway.form.LoginBody;
import com.ruoyi.gateway.service.ValidateCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.*;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.CoreSubscriber;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.util.List;

//@Component
//@Order(0) // 设置过滤器顺序，数字越小优先级越高
public class AuthenticationFilter implements GlobalFilter , Ordered {
    private final static String[] VALIDATE_URL = new String[]{"/system/menu/list"};
    @Autowired
    private WebClient.Builder webClientBuilder;
    @Autowired
    private DiscoveryClient discoveryClient;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        if (StringUtils.equalsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL)) {
            LoginBody loginBody = new LoginBody();
            loginBody.setUsername("admin");
            loginBody.setPassword("admin123");

            List<ServiceInstance> instances = discoveryClient.getInstances("ruoyi-auth");

            if (instances.isEmpty()) {
                throw new RuntimeException("No instances available for user-service");
            }

            // 使用第一个实例的地址
            ServiceInstance instance = instances.get(0);
            String baseUrl = instance.getUri().toString();

            WebClient webClient = webClientBuilder.baseUrl(baseUrl).build();
            // 调用登录接口验证token
            return webClient
                    .post()
                    .uri("/login")
                    .contentType(MediaType.APPLICATION_JSON)
                    .bodyValue(JSON.toJSON(loginBody))
                    .retrieve()
                    .bodyToMono(String.class)
                    .flatMap(res -> {
                        // 可以根据需要对响应进行处理
                        System.out.println(res);
                        JSONObject jsonObject = JSON.parseObject(res);
                        ServerWebExchange modifiedExchange = exchange;
                        System.out.println("Original Request Headers: " + exchange.getRequest().getHeaders());

                        if (200==Integer.valueOf(jsonObject.get("code").toString())){
                            // 获取当前请求的 HttpHeaders
                            HttpHeaders headers = exchange.getRequest().getHeaders();
                            Object data = jsonObject.get("data");
                            JSONObject dataJsonObject = JSON.parseObject(data.toString());
                            ServerHttpRequest modifiedRequest = exchange.getRequest().mutate()
                                    .header("Authorization", "Bearer " + dataJsonObject.get("access_token"))
                                    .build();
                             modifiedExchange = exchange.mutate().request(modifiedRequest).build();
                            System.out.println("Modified Request Headers: " + modifiedRequest.getHeaders());

                        }

                        // 然后继续执行过滤链
                        return chain.filter(modifiedExchange);
                    })
                    .onErrorResume(e -> {
                        System.out.println(e);
                        // 处理异常，返回错误响应
                        ServerHttpResponse response = exchange.getResponse();
                        System.out.println(response);
                        response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
                        return exchange.getResponse().setComplete();
                    });
        } else {
            return chain.filter(exchange);
        }
    }
    @Override
    public int getOrder() {
        return -201;
    }
}
